package com.sinodata.bsm.cicp.collector.oracle;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.AbstractJDBCCollector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.DBConnectionUtil;
import com.sinodata.bsm.common.constants.SeparatorConstants;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 *
 * <p>
 * Description: Oracle 无效对象
 * </p>
 *
 * @author Chao.Liu
 * @version 3.1

 * <p>
 * History:
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2011-11-7 下午1:48:01          Chao.Liu        3.1         To create
 * </p>
 *
 * @since
 * @see
 */
public class InvalidProceduresCollector extends AbstractJDBCCollector {
    private final Logger logger = Logger.getLogger(InvalidProceduresCollector.class);

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        String[] propMetas = getPropMeta();
        try {
            String rsStr = this.getField(ip);
            ResPropertyValue propertyValueX = new ResPropertyValue();
            ResPropertyValue.PropValue[] propValues = new ResPropertyValue.PropValue[propMetas.length];
            for (int i = 0; i < propMetas.length; i++) {
                propValues[i] = ResPropertyValue.createPropValue(rsStr, propMetas[i]);
            }
            propertyValueX.setValues(propValues);
            values.add(propertyValueX);
        } catch (Exception e) {
            logger.error("failed to collect oracle invalid procedures", e);
            throw new CollectorException(e);
        }
        return values;
    }

    private String getField(String ip) throws CollectorException {
        String dbname = this.getParamMap().get("DBName").trim();
        String dbtype = this.getParamMap().get("DBType").trim();
        String sql = this.getParamMap().get("SQL").trim();
        int pageTabColumnsLen = this.getPageTabColumns().length;

        CallableStatement cstmt = null;
        ResultSet rst = null;
        Connection conn = null;

        StringBuffer sb = new StringBuffer();
        //添加无效对象的英文表头
        //sb.append(this.getPageTabColumnsStr()); // Get the title of the table on page

        try {
            conn = DBConnectionUtil.getInstance().getConnection(dbtype, ip, dbname);
            cstmt = conn.prepareCall(sql);
            rst = cstmt.executeQuery();

            if (rst != null) {
                while (rst.next()) {
                    String line = getTabLineStr(rst, pageTabColumnsLen);
                    sb.append(line).append(SeparatorConstants.LIN_SEPARATOR);
                }
            }

        } catch (SQLException sqle) {
            logger.error("Collecting oralce invalid procedures", sqle);
            throw new CollectorException(sqle);
        } catch (Exception ioex) {
            logger.error("Collecting oralce invalid procedures", ioex);
            throw new CollectorException(ioex);
        } finally {
            try {
                if (rst != null) {
                    rst.close();
                }
                if (cstmt != null) {
                    cstmt.close();
                }
                DBConnectionUtil.getInstance().returnConnection(conn);
            } catch (SQLException e) {
                logger.error("failed to close database", e);
                throw new CollectorException(e);
            }
        }

        return sb.toString();
    }

    private String getPageTabColumnsStr() { // Organizational forms on the title page
        StringBuffer sb = new StringBuffer();

        for (String s : this.getPageTabColumns()) {
            sb.append(s + SeparatorConstants.COL_SEPARATOR);
        }

        sb.append(SeparatorConstants.LIN_SEPARATOR);

        return sb.toString();
    }

    private String getTabLineStr(ResultSet rst, int colNum) throws CollectorException {
        StringBuffer tabLineStr = new StringBuffer();
        try {
            for (int i = 1; i <= colNum; i++) {
                String val = rst.getString(i);
                if (val == null || val.trim().length() == 0) {
                    val = " ";
                } else {
                    val = val.trim();
                }
                tabLineStr.append(val).append(SeparatorConstants.COL_SEPARATOR);
            }
        } catch (Exception e) {
            logger.error("failed to get oracle invalid procedures TabLineStr", e);
            throw new CollectorException(e);
        }
        return tabLineStr.toString();
    }

    @Override
    public String[] getPropMeta() { // And the corresponding script
        return new String[] { "$1" };
    }

    @Override
    public String[] getParamMeta() { // These three parameters from the script
        return new String[] { "DBName", "DBType", "SQL" };
    }

    public String[] getPageTabColumns() { // The title Columns on the page table
        //所有者|对象类型|对象名称|状态
        return new String[] { "Owner", "Object Type", "Object Name", "Status" };
    }
}
